<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Java面试宝之基础篇 | Hexo</title>
  <meta name="keywords" content=" interview ">
  <meta name="description" content="Java面试宝之基础篇 | Hexo">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:type" content="website">
<meta property="og:title" content="Tools Hexo">
<meta property="og:url" content="http://huasir.gitee.io/blog/tools/hexo.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-06-24T14:07:55.000Z">
<meta property="article:modified_time" content="2020-06-24T14:07:55.825Z">
<meta property="article:author" content="New Wang">
<meta name="twitter:card" content="summary">


<link rel="icon" href="/img/avatar.jpg">

<link href="/blog/css/style.css?v=1.1.0" rel="stylesheet">

<link href="/blog/css/hl_theme/darcula.css?v=1.1.0" rel="stylesheet">

<link href="//cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css" rel="stylesheet">

<script src="//cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="/blog/js/titleTip.js?v=1.1.0" ></script>

<script src="//cdn.jsdelivr.net/npm/highlightjs@9.16.2/highlight.pack.min.js"></script>
<script>
    hljs.initHighlightingOnLoad();
</script>

<script src="//cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js"></script>



<script src="//cdn.jsdelivr.net/npm/jquery.cookie@1.4.1/jquery.cookie.min.js" ></script>

<script src="/blog/js/iconfont.js?v=1.1.0" ></script>

<meta name="generator" content="Hexo 4.2.1"></head>
<div style="display: none">
  <input class="theme_disqus_on" value="false">
  <input class="theme_preload_comment" value="">
  <input class="theme_blog_path" value="/blog">
  <input id="theme_shortcut" value="true" />
</div>


<body>
<aside class="nav">
    <div class="nav-left">
        <a href="/blog/" class="avatar_target">
    <img class="avatar" src="/blog/img/avatar.jpg" />
</a>
<div class="author">
    <span>New Wang</span>
</div>

<div class="icon">
    
        
        <a title="rss" href="/atom.xml" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-rss"></use>
                </svg>
            
        </a>
        
    
        
        <a title="email" href="mailto:744539648@qq.com" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-email"></use>
                </svg>
            
        </a>
        
    
        
        <a title="qq" href="http://wpa.qq.com/msgrd?v=3&uin=744539648&site=qq&menu=yes" target="_blank">
            
                <svg class="iconfont-svg" aria-hidden="true">
                    <use xlink:href="#icon-qq"></use>
                </svg>
            
        </a>
        
    
</div>




<ul>
    <li><div class="all active" data-rel="全部文章">全部文章<small>(5)</small></div></li>
    
        
            
            <li><div data-rel="Java">Java<small>(4)</small></div>
                
            </li>
            
        
    
        
            
            <li><div data-rel="Tool">Tool<small>(1)</small></div>
                
            </li>
            
        
    
</ul>
<div class="left-bottom">
    <div class="menus">
    
    
    
    
    </div>
    <div><a class="about  hasFriend  site_url"  href="/about">关于</a><a style="width: 50%"  class="friends">友链</a></div>
</div>
<input type="hidden" id="yelog_site_posts_number" value="5">

<div style="display: none">
    <span id="busuanzi_value_site_uv"></span>
    <span id="busuanzi_value_site_pv"></span>
</div>

    </div>
    <div class="nav-right">
        <div class="friends-area">
    <div class="friends-title">
        友情链接
        <i class="iconfont icon-left"></i>
    </div>
    <div class="friends-content">
        <ul>
            
            <li><a target="_blank" href="http://yelog.org/">叶落阁</a></li>
            
        </ul>
    </div>
</div>
        <div class="title-list">
    <div class="right-top">
        <div id="default-panel">
            <i class="iconfont icon-search" data-title="搜索 快捷键 i"></i>
            <div class="right-title">全部文章</div>
            <i class="iconfont icon-file-tree" data-title="切换到大纲视图 快捷键 w"></i>
        </div>
        <div id="search-panel">
            <i class="iconfont icon-left" data-title="返回"></i>
            <input id="local-search-input" />
            <label class="border-line" for="input"></label>
            <i class="iconfont icon-case-sensitive" data-title="大小写敏感"></i>
            <i class="iconfont icon-tag" data-title="标签"></i>
        </div>
        <div id="outline-panel" style="display: none">
            <div class="right-title">大纲</div>
            <i class="iconfont icon-list" data-title="切换到文章列表"></i>
        </div>
    </div>

    <div class="tags-list">
    <input id="tag-search" />
    <div class="tag-wrapper">
        
            <li class="article-tag-list-item">
                <i class="iconfont icon-tag"></i><a>bigdata</a>
            </li>
        
            <li class="article-tag-list-item">
                <i class="iconfont icon-tag"></i><a>Gitee</a>
            </li>
        
            <li class="article-tag-list-item">
                <i class="iconfont icon-tag"></i><a>Hexo</a>
            </li>
        
            <li class="article-tag-list-item">
                <i class="iconfont icon-tag"></i><a>interview</a>
            </li>
        
            <li class="article-tag-list-item">
                <i class="iconfont icon-tag"></i><a>Jvm</a>
            </li>
        
    </div>

</div>

    
    <nav id="title-list-nav">
        
        <a  class="全部文章 Java "
           href="/blog/2020/07/16/BigDateInterview/"
           data-tag="interview,bigdata"
           data-author="" >
            <span class="post-title" title="大数据面试宝典">大数据面试宝典</span>
            <span class="post-date" title="2020-07-16 22:51:06">2020/07/16</span>
        </a>
        
        <a  class="全部文章 Java "
           href="/blog/2020/07/08/JavaInterview/"
           data-tag="interview"
           data-author="" >
            <span class="post-title" title="Java面试宝之基础篇">Java面试宝之基础篇</span>
            <span class="post-date" title="2020-07-08 20:13:11">2020/07/08</span>
        </a>
        
        <a  class="全部文章 Java "
           href="/blog/2020/06/26/jvmLoadClass/"
           data-tag="Jvm"
           data-author="" >
            <span class="post-title" title="JAVA虚拟机的类加载机制（二）">JAVA虚拟机的类加载机制（二）</span>
            <span class="post-date" title="2020-06-26 23:06:18">2020/06/26</span>
        </a>
        
        <a  class="全部文章 Java "
           href="/blog/2020/06/25/JvmLifeCycle/"
           data-tag="Jvm"
           data-author="" >
            <span class="post-title" title="JAVA虚拟机的生命周期（一）">JAVA虚拟机的生命周期（一）</span>
            <span class="post-date" title="2020-06-25 15:13:11">2020/06/25</span>
        </a>
        
        <a  class="全部文章 Tool "
           href="/blog/2020/06/24/hexo/"
           data-tag="Hexo,Gitee"
           data-author="" >
            <span class="post-title" title="Hexo码云个人博客">Hexo码云个人博客</span>
            <span class="post-date" title="2020-06-24 17:16:28">2020/06/24</span>
        </a>
        
        <div id="no-item-tips">

        </div>
    </nav>
    <div id="outline-list">
    </div>
</div>
    </div>
    <div class="hide-list">
        <div class="semicircle" data-title="切换全屏 快捷键 s">
            <div class="brackets first"><</div>
            <div class="brackets">&gt;</div>
        </div>
    </div>
</aside>
<div id="post">
    <div class="pjax">
        <article id="post-JavaInterview" class="article article-type-post" itemscope itemprop="blogPost">
    
        <h1 class="article-title">Java面试宝之基础篇</h1>
    
    <div class="article-meta">
        
        
        
        <span class="book">
            <i class="iconfont icon-category"></i>
            
            
            <a  data-rel="Java">Java</a>
            
        </span>
        
        
        <span class="tag">
            <i class="iconfont icon-tag"></i>
            
            <a class="color5">interview</a>
            
        </span>
        
    </div>
    <div class="article-meta">
        
            发布时间 : <time class="date" title='最后更新: 2020-07-16 21:33:15'>2020-07-08 20:13</time>
        
    </div>
    <div class="article-meta">
        
        
        <span id="busuanzi_container_page_pv">
            阅读 :<span id="busuanzi_value_page_pv">
                <span class="count-comment">
                    <span class="spinner">
                      <div class="cube1"></div>
                      <div class="cube2"></div>
                    </span>
                </span>
            </span>
        </span>
        
        
    </div>
    
    <div class="toc-ref">
    
        <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#参考文献"><span class="toc-text">参考文献</span></a></li></ol>
    
<style>
    .left-col .switch-btn,
    .left-col .switch-area {
        display: none;
    }
    .toc-level-3 i,
    .toc-level-3 ol {
        display: none !important;
    }
</style>
</div>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>###</p>
<ol>
<li>面向对象的特点有哪些？</li>
</ol>
<ul>
<li>抽象，继承，封装，多态</li>
</ul>
<ol start="2">
<li>接口和抽象类有什么区别？</li>
</ol>
<ul>
<li>实现上：抽象类使用继承extend 接口使用实现implement，前者只能单继承，后者和多实现</li>
<li>构造方法：抽象类可以有构造方法，接口不能有构造方法</li>
<li>成员变量：抽象类可以有成员变量，接口不能有成员变量，但可以有final静态常量</li>
<li>方法上：抽象类可以有普通方法，接口不可以有普通方法；抽象类方法的抽象方法可以是protected，接口中的抽象方法只能public</li>
</ul>
<ol start="3">
<li>重载和重写有什么区别？</li>
</ol>
<ul>
<li>重写的实现，但方法定义不能变；重载的是方法名，但方法定义入口不同</li>
<li>重写主要是父类和子类直接；重载的方法名称一样，但参数个数，类型，顺序至少有一个不一样</li>
</ul>
<ol start="4">
<li>java有哪些基本类型</li>
</ol>
<ul>
<li>byte ,short,int,long,float,double,boolean,char</li>
</ul>
<ol start="5">
<li>数组有没有length()方法?String有没有length()方法?</li>
</ol>
<ul>
<li>数组没有length()方法，它有length属性。</li>
<li>String有length()方法。</li>
<li>集合求长度用size()方法。</li>
</ul>
<ol start="6">
<li>Java支持的数据类型有哪些?什么是自动拆装箱?</li>
</ol>
<ul>
<li>8种基础类型</li>
<li>自动装箱: 就是将基本数据类型自动转换成对应的包装类</li>
<li>自动拆箱：就是将包装类自动转换成对应的基本数据类型。</li>
<li>将基本数据类型放入集合类 取出集合数据赋值基础类型</li>
<li>包装类型和基本类型的大小比较equals 和 ==</li>
<li>包装类型的运算</li>
<li>函数返回值和调用函数赋值</li>
</ul>
<ol start="7">
<li>int 和 Integer 有什么区别?</li>
</ol>
<p><strong>基础比较</strong> </p>
<ul>
<li>基础类型和封装类型</li>
<li>速度快和速度慢</li>
<li>栈取和堆区</li>
<li>初始值0和null</li>
</ul>
<p><strong>深度比较</strong></p>
<pre><code>     Integer i = new Integer(100);
     Integer j = new Integer(100);
     System.out.println(i.equals(j));
     System.out.println(i==j);</code></pre><p>运行结果</p>
<pre><code>    true
    false</code></pre><p>结论：Integer重新equals采用intvalue进行比较，故为true。第二个false比较两个不同的对象</p>
<pre><code>    Integer a = 100;
    Integer b = new Integer(100);        

    System.out.println(a==b);

    Integer c = 100;
    System.out.println(a==c);

    Integer d = 128;
    Integer f = 128;
    System.out.println(d==f); </code></pre><p>运行结果：</p>
<pre><code>    false
    true
    false</code></pre><p>结论：</p>
<ul>
<li>非new生成的integer变量指向的是静态常量池中的cache数组中存储的指向Integer对象;</li>
<li>而new integer生成的变量指向堆中,两者在内存中的对象引用地址不同</li>
<li>Integer的值会进行缓存[-128到127]之外的数,被装箱后的Integer对象并不会被重用，即相当于每次装箱时都新建一个Integer对象。</li>
</ul>
<ol start="8">
<li>Java实例化顺序？ </li>
</ol>
<ul>
<li>父类静态成员和静态代码块 -&gt; 子类静态成员和静态代码块 -&gt; </li>
<li>父类非静态成员和非静态代码块 -&gt; 父类构造方法 -&gt; 子类非静态成员和非静态代码块 -&gt; 子类构造方法</li>
</ul>
<ol start="9">
<li>什么是值传递和引用传递?<pre><code> int num =20;
 String str = &quot;hello&quot;;</code></pre></li>
</ol>
<ul>
<li><p>基础类型num，值保存在变量中；引用类型str变量中保存的是实际对象的地址</p>
</li>
<li><p>=，对于基础类型num，赋值运算直接改变变量的值，原来的值被覆盖</p>
</li>
<li><p>=，对应引用类型str，赋值会改变引用中保存的地址，原来的地址会被覆盖。原来的对象不会改变。</p>
</li>
<li><p>方法调用，实际上是赋值操作</p>
<pre><code>  public class TestString {
      public static void main(String[] args) {
          int num = 20;
          String str = &quot;hello&quot;;
          TestString t = new TestString();
          System.out.println(&quot;before foo &quot;+num);
          t.foo(num);
          System.out.println(&quot;after foo &quot;+num);

          System.out.println(&quot;before foo &quot;+str);
          t.foo(str);
          System.out.println(&quot;after foo &quot;+str);

          StringBuilder sb = new StringBuilder(&quot;iphone&quot;);
          System.out.println(&quot;before foo &quot;+sb);
          t.foo(sb);
          System.out.println(&quot;after foo &quot;+sb);

          StringBuilder sb2 = new StringBuilder(&quot;iphone&quot;);
          System.out.println(&quot;before foo &quot;+sb2);
          t.foo2(sb2);
          System.out.println(&quot;after foo &quot;+sb2);
      }

      void foo(int value) {
          value = 100;
      }
      void foo(String text) { //没有提供改变自身方法的引用类型,对text赋值
          text = &quot;windows&quot;;
      }

      void foo(StringBuilder builder) { //提供了改变自身方法的引用类型
          builder.append(&quot;4&quot;);
      }

      void foo2(StringBuilder builder) {//提供了改变自身方法的引用类型 但是不使用，而是使用赋值运算符
          builder = new StringBuilder(&quot;ipad&quot;);
      }
  }</code></pre><p>运行结果：</p>
<pre><code>  before foo 20
  after foo 20
  before foo hello
  after foo hello
  before foo iphone
  after foo iphone4
  before foo iphone
  after foo iphone</code></pre></li>
</ul>
<ol start="10">
<li>String和StringBuilder、StringBuffer的区别?</li>
</ol>
<ul>
<li>StringBuilder线程不安全，快</li>
<li>StringBuffer 线程安全，慢</li>
<li>String 更慢</li>
</ul>
<ol start="11">
<li>Map和集合有什么关系？</li>
</ol>
<ul>
<li>Map是集合框架的一部分，但Map不是集合。</li>
</ul>
<ol start="12">
<li>Map有哪些实现，各有什么特点？</li>
</ol>
<ul>
<li><p>HashMap 无序，线程不安全，LinkedHashMap（迭代次序有序）,</p>
<pre><code>  Map&lt;String, String&gt; map = new HashMap&lt;&gt;();
  map.put(&quot;name1&quot;,&quot;key1&quot;);
  map.put(&quot;name2&quot;,&quot;key2&quot;);
  map.put(&quot;name3&quot;,&quot;key3&quot;);
  map.forEach((k,v)-&gt;{
      System.out.println(&quot;name: &quot;+k+&quot;  value: &quot;+v);
  });

  Map&lt;String, String&gt; lmap = new LinkedHashMap&lt;&gt;();
  lmap.put(&quot;name1&quot;,&quot;key1&quot;);
  lmap.put(&quot;name2&quot;,&quot;key2&quot;);
  lmap.put(&quot;name3&quot;,&quot;key3&quot;);
  lmap.forEach((k,v)-&gt;{
      System.out.println(&quot;name: &quot;+k+&quot;  value: &quot;+v);
  });</code></pre></li>
</ul>
<p>运行结果：</p>
<pre><code>    name: name3  value: key3
    name: name2  value: key2
    name: name1  value: key1
    name: name1  value: key1
    name: name2  value: key2
    name: name3  value: key3</code></pre><p>LinkedHashMap在HashMap的基础增加了 before和after指针保存插入顺序</p>
<ul>
<li><p>HashTable 线程安全，建议使用ConcurrentHashMap</p>
</li>
<li><p>SortedMap-TreeMap(log(n)时间增删改查，性能平均)</p>
<p>通过parent，left，right已经color属性的Entry实现红黑树</p>
</li>
<li><p>WeakHashMap 具有弱键key，当key不被使用时，会被回收</p>
</li>
</ul>
<ol start="13">
<li>集合有哪些实现，各有什么特点？</li>
</ol>
<ul>
<li>List有序集元<ol>
<li>ArrayList 利用下标访问，效率高</li>
<li>LinkedList 链表访问，插入删除效率高</li>
<li>Vector 同步方法，不常用</li>
</ol>
</li>
<li>Set无序集<ol>
<li>HashSet 访问效率高，不允许重复元素 ,内部采用HashMap实现</li>
<li>SortedSet 有序，不允许重复，TreeSet红黑树实现 内部采用TreeMap实现</li>
</ol>
</li>
<li>Queue 队列<ol>
<li>LinkedBlockingQueue    </li>
</ol>
</li>
</ul>
<ol start="14">
<li><p>集合删除遍历和add遍历</p>
<pre><code>public static void main(String[] args) {
    List&lt;String&gt; l =new  ArrayList&lt;&gt;();
    l.add(&quot;one&quot;);
    l.add(&quot;two&quot;);
    l.add(&quot;three&quot;);
    System.out.println(l.size());
    try {
        l.forEach(m -&gt; {
            if (m.equals(&quot;two&quot;)) l.remove(m);
        });
    }catch (Exception e){
        System.out.println(&quot;exception and size is &quot; +l.size());
    }

    Iterator it = l.iterator();
    while (it.hasNext()){
        if(it.next().equals(&quot;two&quot;))it.remove();
    }
    System.out.println(l.size());

    ListIterator&lt;String&gt; lit = l.listIterator();
    while (lit.hasNext()){
        String item =lit.next();
        System.out.println(item);
        if(item.equals(&quot;one&quot;))lit.add(&quot;two&quot;);
    }
    System.out.println(l.size());
}</code></pre><p>输出结果：</p>
</li>
</ol>
<pre><code>    3
    exception and size is 2
    2
    one
    three
    3</code></pre><ol start="15">
<li>HashMap和HashTable有何不同？</li>
</ol>
<ul>
<li>HashMap允许key和value为null，HashTable不可以</li>
<li>HashMap不是同步的，HashTable是线程同步的</li>
<li>HashTable是遗留类，可以用ConcurrentHashMap替换</li>
</ul>
<ol start="16">
<li><p>如何决定选用HashMap还是TreeMap？<br>如果你数据是有序的那就用TreeMap</p>
</li>
<li><p>Array和ArrayList有何区别？什么时候更适合用Array？</p>
</li>
</ol>
<ul>
<li>Array可以容纳基本类型和对象，ArrayList只能容纳对象</li>
<li>Array是指定大小的，ArrayList大小是动态变化的</li>
</ul>
<ol start="18">
<li><p>ArrayList和LinkedList有何区别？<br>Array随机访问，随机修改方便<br>LinkedList随机移动元素，增加，删除比较快</p>
</li>
<li><p>throw 和 throws有什么区别？<br>throw抛出一个什么异常，用作方法体里面<br>throws会抛什么异常，用作方法声明处</p>
</li>
<li><p>final和finally有什么区别<br>final声明变量和方法时用<br>finally异常处理的一部分</p>
</li>
<li><p>描述java内存模型？</p>
</li>
</ol>
<p>java内测模型和物理机模型类似</p>
<p><img src="http://assets.processon.com/chart_image/5f07427af346fb3fdc62088d.png" alt="java内测模型和物理机模型类似"></p>
<p><strong>并发模型</strong></p>
<p>java内存模型是共享内存的并发模型，线程直接主要通过读写共享变量（堆内存中的实例域、静态域、数组）来完成隐式通信</p>
<p><strong>一致性控制</strong></p>
<p>java内存模型控制着java线程间的通信，决定一个线程对共享变量的写入何时对另一个线程可见</p>
<ol start="22">
<li>java内存模型，解决什么问题？</li>
</ol>
<ul>
<li><p>在多线程并发情况下，如何处理多线程读同步问题与可见性（多线程缓存与指令重排序）</p>
<p>如果两个或更多线程在没有正确使用volatile声明或同步的情况下共享一个变量，一个线程对这个共享变量的修改对其它线程来说不可见<br>怎么去解决这个问题？</p>
<ol>
<li>java中的volatile关键字，volatile可以保证直接从主存中读取一个变量，如果这个变量被修改，总是会被写回主存中</li>
<li>java中synchronized，如果对一个变量lock操作，会清空工作内存中此变量的值，对一个变量unlock，必须把此变量同步回主存</li>
<li>java中final关键字</li>
</ol>
<p>重排序导致的可见性，怎么解决？</p>
<ol>
<li>valatile本身禁止指令重排序</li>
<li>synchronize是由”一个变量在同一时间，只能允许一个线程对其lock操作”，觉定了持有同一个锁的两个同步块只能串行执行</li>
</ol>
<p><strong>重排序有哪些</strong></p>
<p>源代码-&gt;编译器优化重排序-&gt;指令级重排序-&gt;内存系统重排序-&gt;最终执行的指令序列</p>
<p>编译器和指令集重排序，遵循数据依赖原则，不同处理器不同线程则忽视 如下：</p>
<p>这里假设有两个线程A和B，A首先执行writer()方法，随后B线程接着执行reader()方法。线程B在执行操作4时，能否看到线程A在操作1对共享变量a的写入呢? 不一定</p>
<pre><code>  public class ReorderExample {
      int a=0;
      boolean flag =false;

      public void write(){
          a=1; //1
          flag=true; //2
      }
      public void reader(){
          if(flag){//3
              int i =a*a;//4
          }
      }
  }</code></pre><p> 为了保证内存可见性，Java编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序</p>
<p> 屏障类型有那些？<br> LoadLoad StoreStore LoadStore StoreLoad</p>
</li>
<li><p>多线程写同步与原子性（多线程竞争race condtition）</p>
<p>当读，写和检查共享变量时出现race conditions 数据竞争，出现共享数据不一致</p>
<p>什么是原子性？</p>
<p>要么该操作不被执行；要么以原子方式执行，即执行过程中不会被其它线程中断</p>
</li>
</ul>
<ol start="23">
<li><p>volatile陷阱</p>
<p>volatile关键字对于基本类型的修改可以在随后对多个线程的读保持一致，但是对于引用类型如数组，实体bean，仅仅保证引用的可见性，但并不保证引用内容的可见性</p>
</li>
<li><p>java中垃圾收集的方法有哪些?</p>
</li>
</ol>
<p><strong>怎么定义垃圾</strong></p>
<ul>
<li><p>引用计数算法Reachability Counting： 对象头中分配一个空间来保存该对象被引用的次数，该对象被其它对象引用，则它的引用计数加1，如果删除对该对象的引用，那么它的引用计数就减1，当该对象的引用计数为0时，那么该对象就会被回收。<strong>循环引用问题</strong></p>
</li>
<li><p>可达性分析算法Reachability Analysis：过一些被称为引用链（GC Roots）的对象作为起点，从这些节点开始向下搜索，搜索走过的路径被称为（Reference Chain)，当一个对象到 GC Roots 没有任何引用链相连时（即从 GC Roots 节点到该节点不可达），则证明该对象是不可用的</p>
<p> GC Roots：</p>
<ol>
<li><p>虚拟机栈（栈帧中的本地变量表）中引用的对象</p>
</li>
<li><p>方法区中类静态属性引用的对象</p>
</li>
<li><p>方法区中常量引用的对象</p>
</li>
<li><p>本地方法栈中 JNI（即一般说的 Native 方法）引用的对象</p>
<pre><code>public static class StackLocalParameter {
  public StackLocalParameter(String name) {
  }
}    
public static void testGC() {
  StackLocalParameter s = new StackLocalParameter(&quot;localParameter&quot;); ////GCRoot 虚拟机栈（栈帧中的本地变量表）中引用的对象
  s = null; //s 回收
}    
public static class MethodAreaStaicProperties {
  public static MethodAreaStaicProperties m; //GC Root

  public MethodAreaStaicProperties(String name) {
  }
}    
public static void testGC2() {
  MethodAreaStaicProperties s = new MethodAreaStaicProperties(&quot;properties&quot;);
  s.m = new MethodAreaStaicProperties(&quot;parameter&quot;); //GCRoot 方法区中类静态属性引用的对象
  s = null; //s 为 GC Root，s 置为 null，经过 GC 后，s 所指向的 properties 对象由于无法与 GC Root 建立关系被回收
            //而 m 作为类的静态属性，也属于 GC Root，parameter 对象依然与 GC root 建立着连接，所以此时 parameter 对象并不会被回收。
}    
public static class MethodAreaStaicProperties2 {
  public static final MethodAreaStaicProperties2 m = new MethodAreaStaicProperties2(&quot;final&quot;);//GCRoot
  public MethodAreaStaicProperties2(String name) {
  }
}    
public static void testGC3() {
  MethodAreaStaicProperties2 s = new MethodAreaStaicProperties2(&quot;staticProperties&quot;);
  s = null;//m 即为方法区中的常量引用，也为 GC Root，s 置为 null 后，final 对象也不会因没有与 GC Root 建立联系而被回收。
}</code></pre></li>
</ol>
</li>
</ul>
<p><strong>怎么回收垃圾</strong></p>
<ul>
<li><p>标记 — 清除算法：先把内存区域中的这些对象进行标记，哪些属于可回收标记出来，然后把这些垃圾拎出来清理掉，<strong>内存碎片化</strong>问题</p>
</li>
<li><p>复制算法：它将可用内存按容量划分为大小相等的两块，每次只使用其中的一块。当这一块的内存用完了，就将还存活着的对象复制到另外一块上面，然后再把已使用过的内存空间一次清理掉， <strong>内存成本高</strong></p>
</li>
<li><p>标记整理算法：标记过程仍然与标记 — 清除算法一样，但后续步骤不是直接对可回收对象进行清理，而是让所有存活的对象都向一端移动，再清理掉端边界以外的内存区域，<strong>内存变动更频繁效率底下</strong></p>
</li>
<li><p>分代收集算法：不是一种思想或理论，而是融合上述3种基础的算法思想，在新生代中，每次垃圾收集时都发现有大批对象死去，只有少量存活，那就选用复制算法，只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保，就必须使用标记-清理或者标记 — 整理算法来进行回收</p>
<p>内存模型与回收策略</p>
<ol>
<li>堆空间=新生代（1/3）+老年代（2/3）</li>
<li>新生代 = Eden（8/10）+From(1/10) +To(1/10)</li>
</ol>
<p><strong>Old 区</strong></p>
<p>老年代占据着2/3的堆内存空间，只有在 Major GC 的时候才会进行清理，每次 GC 都会触发“Stop-The-World”,复制操作，效率很低，所以老年代这里采用的是标记 — 整理算法</p>
<p><strong>大对象</strong></p>
<p>大对象指需要大量连续内存空间的对象，这部分对象不管是不是“朝生夕死”，都会直接进到老年代。这样做主要是为了避免在 Eden 区及2个 Survivor 区之间发生大量的内存复制。当你的系统有非常多“朝生夕死”的大对象时，得注意了</p>
<p><strong>长期存活对象</strong></p>
<p>每个对象定义了一个对象年龄（Age）计数器。正常情况下对象会不断的在 Survivor 的 From 区与 To 区之间移动，对象在 Survivor 区中每经历一次 Minor GC，年龄就增加1岁。当年龄增加到15岁时，这时候就会被转移到老年代</p>
<p><strong>动态对象年龄</strong></p>
<p>如果 Survivor 空间中相同年龄所有对象大小的总合大于 Survivor 空间的一半，年龄大于等于该年龄的对象就可以直接进去老年区，无需等你“15岁”</p>
<p><strong>持久带</strong></p>
<p>持久带也称为方法区，用于存放静态文件，如今Java类、方法等，JDK8中已经把持久代（PermGen Space） 干掉了，取而代之的元空间（Metaspace）。Metaspace占用的是本地内存，不再占用虚拟机内存</p>
</li>
</ul>
<ol start="25">
<li><p>什么是类加载器双亲委派模型机制?</p>
<p>如果一个类加载器收到了一个类加载的请求，它首先不会去加载类，而是去把这个请求委派给父加载器去加载，直到顶层启动类加载器，如果父类加载不了（不在父类加载的搜索范围内），才会自己去加载。</p>
<p><strong>类加载器</strong></p>
<ol>
<li>AppClassLoader 寻找classpath目录下</li>
<li>ExtClassLoader 加载 jre/lib/ext路径下的jar包。 1.9废弃改用平台类加载器 PlatformClassLoader</li>
<li>BootStrapClassLoader 加载 JAVA_HOME/lib下的jar包</li>
</ol>
</li>
<li><p>java线程同步的方法有哪些？</p>
<p>多个线程要同时访问一个变量或对象时，如果这些线程中既有读又有写操作时，就会导致变量值或对象的状态出现混乱。</p>
<p><strong>同步方法</strong></p>
<p>即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁，当用此关键字修饰方法时，内置锁会保护整个方法。在调用该方法前，需要获得内置锁，否则就处于阻塞状态。注意，synchronized修饰静态方法锁住的是类</p>
<p><strong>同步代码块</strong></p>
<p>即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁，从而实现同步。</p>
<p>同步是一种高开销的操作，因此应该尽量减少同步的内容。通常没有必要同步整个方法，使用synchronized代码块同步关键代码即可。</p>
<p><strong>特殊域变量(volatile)实现线程同步</strong></p>
<p>但volatile不能保证原子操作导致的，因此volatile不能代替synchronized，能不使用就不使用</p>
<p><strong>重入锁实现线程同步</strong></p>
<p>ReentrantLock实例，ReentrantLock类是可重入、互斥、实现了Lock接口的锁</p>
<p>lock() ：获得锁<br>unlock() ：释放锁<br>和synchronized语义一致</p>
<p>公平锁：每个线程都能拿到锁，缺点是性能没有非公平锁高</p>
<p>非公平锁：获得锁的顺序是杂乱的，效率高，缺点线程饿死</p>
</li>
</ol>
<p><strong>ThreadLocal</strong></p>
<p> ThreadLocal适用的场景是，多个线程都需要使用一个变量，但这个变量的值不需要在各个线程间共享，各个线程都只使用自己的这个变量的值</p>
<p><strong>使用原子变量实现线程同步</strong></p>
<p> util.concurrent.atomic包中提供了创建了原子类型变量的工具类，如AtomicInteger，AtomicLong等，CAS（比较并交换）是CPU指令级的操作，只有一步原子操作，所以非常快。而且CAS避免了请求操作系统来裁定锁的问题，不用麻烦操作系统，直接在CPU内部就搞定了。</p>
<p><strong>使用阻塞队列实现线程同步</strong></p>
<p> BlockingQueue </p>
<ol start="27">
<li><p>解释一下锁的一些基本概念：可重入锁、可中断锁、公平锁、读写锁?</p>
<p><strong>可重入锁</strong></p>
<p>当一个线程执行到某个synchronized方法时，比如说method1，而在method1中会调用另外一个synchronized方法method2，此时线程不必重新去申请锁，而是可以直接执行方法method2</p>
<p><strong>可中断锁</strong></p>
<p>synchronized就不是可中断锁，而Lock是可中断锁。如果某一线程A正在执行锁中的代码，另一线程B正在等待获取该锁，可能由于等待时间过长，线程B不想等待了，想先处理其他事情，我们可以让它中断自己或者在别的线程中中断它，这种就是可中断锁</p>
<p><strong>公平锁</strong></p>
<p>即尽量以请求锁的顺序来获取锁</p>
<p><strong>读写锁</strong></p>
<p>读写锁将对一个资源（比如文件）的访问分成了2个锁，一个读锁和一个写锁。</p>
<p>得多个线程之间的读操作不会发生冲突，ReadWriteLock就是读写锁，它是一个接口，ReentrantReadWriteLock实现了这个接口</p>
</li>
<li><p>synchronized和ReentrantLock有什么区别</p>
<ul>
<li>synchronized在发生异常时，会自动释放线程占有的锁，因此不会导致死锁现象发生；而Lock在发生异常时，如果没有主动通过unLock()去释放锁，则很可能造成死锁现象，因此使用Lock时需要在finally块中释放锁；</li>
<li>Lock可以让等待锁的线程响应中断，而synchronized却不行</li>
<li>Lock可以提高多个线程进行读操作的效率。</li>
<li>在性能上来说，如果竞争资源不激烈，两者的性能是差不多的，而当竞争资源非常激烈时（即有大量线程同时竞争），此时Lock的性能要远远优于synchronized</li>
<li>Lock可以设置等待锁的时间，而synchronized不行</li>
</ul>
</li>
<li><p>CAS（Compare And Swap） 无锁算法： CAS是乐观锁技术，当多个线程尝试使用CAS同时更新同一个变量时，只有其中一个线程能更新变量的值，而其它线程都失败，失败的线程并不会被挂起，而是被告知这次竞争中失败，并可以再次尝试.</p>
</li>
</ol>
<p><strong>ABA问题</strong></p>
<p>线程A进行CAS逻辑，在从内存中获取到var值到开始进行逻辑之间,会有一个时间差;如果刚好在这个时间差内，有其他某线程对var做了一系列的操作,但最后又恢复了var的值，虽然此时线程A仍然能CAS成功，但是中间多出的那些过程仍然可能引发问题</p>
<p><strong>是否需要处理</strong></p>
<p>判断是否处理ABA问题。如果ABA问题并不会影响我们的业务结果，可以选择性处理或不处理;如果ABA会影响我们的业务结果的，这时就必须处理ABA问题了</p>
<p><strong>避免</strong></p>
<p>AtomicMarkableReference 可以给一个引用标记上一个标记位，来保证原子性</p>
<p>AtomicStampedReference 可以给一个引用标记上一个整型的版本戳，来保证原子性</p>
<ol start="29">
<li>线程池的作用有哪些?</li>
</ol>
<ul>
<li>降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。</li>
<li>提高响应速度。当任务到达时，任务可以不需要等到线程创建就能立即执行。</li>
<li>提高线程的可管理性</li>
</ul>
<p><strong>常用线程池</strong></p>
<ul>
<li>Executors.newSingleThreadPool(),</li>
<li>newFixedThreadPool</li>
<li>newCachedTheadPool</li>
<li>newScheduledThreadPool</li>
</ul>
<ol start="29">
<li>差用的反射</li>
</ol>
<ul>
<li>Class.forName</li>
<li>Clazz.getConstructor</li>
<li>Clazz.newInstance</li>
</ul>
<p>优点：灵活性高，缺点：性能损耗</p>
<ol start="30">
<li><p>设计模式详见 <a href="http://c.biancheng.net/design_pattern/" target="_blank" rel="noopener">Java设计模式：23种设计模式全面解析（超级详细</a></p>
</li>
<li><p>常用注解</p>
</li>
</ol>
<ul>
<li>@Overried</li>
<li>@Deprecated</li>
<li>@SuppressWarnings</li>
</ul>
<p><strong>java元注解</strong></p>
<ul>
<li>@Target</li>
<li>@Retention</li>
<li>@Documented </li>
<li>@Inherited</li>
</ul>
<ol start="32">
<li>java8新特性</li>
</ol>
<ul>
<li>Lambda表达式</li>
<li>方法引用</li>
<li>函数接口</li>
<li>默认方法</li>
<li>Stream</li>
<li>Optional</li>
<li>Nashorm，javascript引擎</li>
<li>新的日期api</li>
<li>Base64</li>
</ul>
<ol start="33">
<li>java11新特性</li>
</ol>
<ul>
<li>var 推断</li>
<li>字符串加强</li>
<li>集合加强</li>
<li>Stream加强</li>
<li>Optional加强</li>
<li>InputStream加强</li>
<li>HttpClient重磅（同步，异步，websocket）</li>
</ul>
<ol start="34">
<li>线程安全问题：当一个类被多个线程进行访问并且正确运行，它就是线程安全的</li>
</ol>
<ul>
<li>死锁</li>
<li>脏数据</li>
</ul>
<ol start="35">
<li>什么是死锁</li>
</ol>
<p><strong>死锁出现的场景</strong></p>
<ul>
<li>多线程： 彼此申请对方资源而导致的死锁</li>
<li>但线程： A自己拥有资源，但还要申请新的资源，而新的资源又被占用，则A挂起但不释放资源</li>
</ul>
<p><strong>死锁条件和避免</strong></p>
<ul>
<li>互斥条件 （不可破坏）</li>
<li>请求与保持条件（1. 开始起获得所有资源 2. 请求资源是释放已占用资源）</li>
<li>不可剥夺 （1. 请求资源时抢占别的线程已占用的资源 ）</li>
<li>循环等待 （1. 对请求资源的线程进行线性排序）</li>
</ul>
<p><strong>死锁解除</strong></p>
<ul>
<li>抢占资源</li>
<li>终止或撤销线程</li>
</ul>
<ol start="36">
<li>synchronized 实现原理？</li>
</ol>
<p><strong>两个基础</strong></p>
<ul>
<li>Java对象头</li>
<li>monitor</li>
</ul>
<p><strong>Java对象头</strong></p>
<p>每一个Java类，在被JVM加载的时候，JVM会给这个类创建一个instanceKlass，保存在方法区，用来在JVM层表示该Java类。使用new创建一个对象的时候，JVM会创建一个instanceOopDesc对象，这个对象中包含了两部分信息，<strong>对象头</strong>以及<strong>实例数据</strong>。对象头包含<strong>Mark Word</strong> 和<strong>Klass Point</strong> </p>
<p><strong>Mark Word</strong><br>存储对象自身的运行时数据，如哈希码（HashCode）、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等等,它是实现轻量级锁和偏向锁的关键</p>
<p><strong>Monitor</strong></p>
<p>理解为一个同步工具，也可以描述为一种同步机制</p>
<p><strong>锁优化</strong></p>
<p>自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁 <a href="https://www.jianshu.com/p/46a874d52b71" target="_blank" rel="noopener">深入理解Synchronized实现原理</a></p>
<p>锁主要存在四中状态，依次是：无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态，他们会随着竞争的激烈而逐渐升级</p>
<p>偏向锁的思想：偏向锁是一种针对加锁操作的优化手段，他的核心思想是：如果一个线程获得了锁，那么锁就进入了偏向模式。当这个线程再次请求锁时，无需再做任何同步操作，这样就节省了大量有关锁申请的操作，从而提高了程序的性能。</p>
<ol start="37">
<li>java并发包有哪些？<a href="https://segmentfault.com/a/1190000015558984" target="_blank" rel="noopener">透彻理解Java并发编程系列</a> </li>
</ol>
<p><strong>J.U.C</strong></p>
<ul>
<li>juc-lock 锁框架</li>
<li>juc-atomic 原子类框架</li>
<li>juc-sync 同步器框架</li>
<li>juc-collections 集合框架</li>
<li>juc-excutors 执行器框架</li>
</ul>
<ol start="38">
<li>什么是fast-fail？什么是safe-fail？</li>
<li>什么是copyOnWrite？</li>
</ol>
<p>CopyOnWrite容器即写时复制的容器。通俗的理解是当往一个容器添加元素的时候，不直接往当前容器添加，而是先将当前容器进行Copy，复制出一个新的容器，然后新的容器里添加元素，添加完元素之后，再将原容器的引用指向新的容器。这样做的好处是可以对CopyOnWrite容器进行并发的读，而不需要加锁，因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想，读和写不同的容器。<br><strong>问题</strong></p>
<ul>
<li>内存占用问题：在进行写操作的时候，内存里会同时驻扎两个对象的内存</li>
<li>数据一致性问题： CopyOnWrite容器只能保证数据的最终一致性，不能保证数据的实时一致性</li>
</ul>
<ol start="40">
<li>什么是AQS呢？<a href="https://www.jianshu.com/p/0f876ead2846" target="_blank" rel="noopener">浅谈Java的AQS</a></li>
<li>乐观锁悲观锁区别是什么？</li>
</ol>
<ul>
<li>乐观锁：总是假设最好的情况，认为竞争总是不存在，每次拿数据的时候都认为不会被修改，因此不会先上锁，在最后更新的时候比较数据有无更新，可通过版本号或CAS实现。用于读比较多的情况</li>
<li>悲观锁：总是假设最坏的情况，认为竞争总是存在，每次拿数据的时候都认为会被修改，因此每次都会先上锁。其他线程阻塞等待释放锁。用于写比较多的情况</li>
</ul>
<ol start="42">
<li>数据库如何实现悲观锁和乐观锁？</li>
</ol>
<ul>
<li>悲观锁实现：使用数据库自带的锁机制 select  — for update 可能为行锁，如果为多行可能为表锁 <a href="https://www.iteye.com/blog/chenzhou123520-1860954" target="_blank" rel="noopener">mysql悲观锁总结和实践</a></li>
<li>乐观锁实现：给表加字段version或timestamp来实现</li>
</ul>
<ol start="43">
<li>锁与隔离级别的关系</li>
</ol>
<ul>
<li><p>Read uncommitted</p>
<p>读未提交，顾名思义，就是一个事务可以读取另一个未提交事务的数据。（脏读）</p>
</li>
<li><p>Read committed</p>
<p>读提交，顾名思义，就是一个事务要等另一个事务提交后才能读取数据。可以解决脏读问题，不可重复读</p>
</li>
<li><p>Repeatable read</p>
<p>重复读，就是在开始读取数据（事务开启）时，不再允许修改操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作，而不是UPDATE操作</p>
</li>
<li><p>Serializable 序列化</p>
<p>Serializable 是最高的事务隔离级别，在该级别下，事务串行化顺序执行，可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下，比较耗数据库性能，一般不使用</p>
</li>
</ul>
<ol start="44">
<li>数据库索引</li>
</ol>
<p><strong>存储引擎</strong></p>
<ul>
<li>Inodb粗糙引擎默认是B+Tree索引</li>
<li>MyISAM默认引擎是Fulltext索引</li>
<li>Memory存储引擎默认是Hash索引</li>
</ul>
<p><strong>什么是索引</strong></p>
<p>索引（Index）是帮助数据库高效获取数据的数据结构。索引是在基于数据库表创建的，它包含一个表中某些列的值以及记录对应的地址，并且把这些值存储在一个数据结构中</p>
<p><strong>为什么平衡二叉树也不适合作为索引</strong></p>
<p>我们说的平衡二叉树结构，指的是逻辑结构上的平衡二叉树，其物理实现是数组。然后由于在逻辑结构上相近的节点在物理结构上可能会差很远。因此，每次读取的磁盘页的数据中有许多是用不上。</p>
<p><strong>B-Tree适合作为索引</strong></p>
<p>使用红黑树（平衡二叉树）结构的话，每次磁盘预读中的很多数据是用不上的数据。因此，它没能利用好磁盘预读的提供的数据。然后又由于深度大（较B树而言），所以进行的磁盘IO操作更多。B树的每个节点可以存储多个关键字，它将节点大小设置为磁盘页的大小，充分利用了磁盘预读的功能。每次读取磁盘页时就会读取一整个节点。也正因每个节点存储着非常多个关键字，树的深度就会非常的小。进而要执行的磁盘读取操作次数就会非常少，更多的是在内存中对读取进来的数据进行查找。B树的查询，主要发生在内存中，而平衡二叉树的查询，则是发生在磁盘读取中。因此，虽然B树查询查询的次数不比平衡二叉树的次数少，但是相比起磁盘IO速度，内存中比较的耗时就可以忽略不计了。因此，B树更适合作为索引。</p>
<p><strong>比B树更适合作为索引的结构——B+树</strong></p>
<p>数据库索引采用B+树的主要原因是B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。正是为了解决这个问题，B+树应运而生。<br>B+树只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的，而B树不支持这样的操</p>
<p><strong>索引结构</strong></p>
<ul>
<li>非叶子节点：索引数据项和指针，不存储真实数据</li>
<li>叶子节点：真实数据想</li>
</ul>
<p><strong>注意</strong><br>io次数决定于高度，高度决定于索引大小</p>
<p>索引尽量小；索引最左匹配</p>
<h3 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h3><p><a href="https://blog.csdn.net/pianai_s/article/details/89762176" target="_blank" rel="noopener">Java全栈开发</a></p>
<p><a href="https://www.cnblogs.com/aishangJava/tag/java%E9%9D%A2%E8%AF%95%E9%A2%98/" target="_blank" rel="noopener">java面试题</a></p>
<p><a href="https://www.jianshu.com/p/8f4f58b4b8ab" target="_blank" rel="noopener">图解LinkedHashMap原理</a></p>
<p><a href="https://www.cnblogs.com/LiaHon/p/11203229.html" target="_blank" rel="noopener">关于红黑树(R-B tree)原理</a></p>
<p><a href="https://www.cnblogs.com/LiaHon/p/11221634.html" target="_blank" rel="noopener">TreeMap原理实现及常用方法</a></p>
<p><a href="https://www.iteye.com/blog/shmilyaw-hotmail-com-1700600" target="_blank" rel="noopener">集合类深入分析之HashSet, HashMap篇</a></p>
<p><a href="https://www.cnblogs.com/czwbig/p/11127124.html" target="_blank" rel="noopener">Java内存区域（运行时数据区域）和内存模型（JMM）</a></p>
<p><a href="https://zhuanlan.zhihu.com/p/29881777" target="_blank" rel="noopener">Java内存模型（JMM）总结</a></p>
<p><a href="https://www.jianshu.com/p/15106e9c4bf3" target="_blank" rel="noopener">深入理解Java内存模型</a></p>
<p><a href="https://blog.csdn.net/u010454030/article/details/80800098" target="_blank" rel="noopener">Java里面volatile关键字修饰引用变量的陷阱</a></p>
<p><a href="https://baijiahao.baidu.com/s?id=1639843226656912938&wfr=spider&for=pc" target="_blank" rel="noopener">咱们从头到尾说一次 Java 垃圾回收</a></p>
<p><a href="https://www.jianshu.com/p/deb040582060" target="_blank" rel="noopener">深入理解JVM，类加载机制ClassLoader流程</a></p>
<p><a href="http://c.biancheng.net/design_pattern/" target="_blank" rel="noopener">Java设计模式：23种设计模式全面解析（超级详细</a></p>
<p><a href="https://www.jianshu.com/p/46a874d52b71" target="_blank" rel="noopener">深入理解Synchronized实现原理</a></p>
<p><a href="https://segmentfault.com/a/1190000015558984" target="_blank" rel="noopener">透彻理解Java并发编程系列</a></p>
<p><a href="https://www.jianshu.com/p/0f876ead2846" target="_blank" rel="noopener">浅谈Java的AQS</a></p>
<p><a href="https://www.cnblogs.com/LBSer/p/5183300.html" target="_blank" rel="noopener">mysql死锁问题分析</a></p>

      
       <hr><span style="font-style: italic;color: gray;"> 转载请注明来源，欢迎对文章中的引用来源进行考证，欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论，也可以邮件至 744539648@qq.com </span>
    </div>
</article>







    




    </div>
    <div class="copyright">
        <p class="footer-entry">
    ©2016-2020 Yelog
</p>
<p class="footer-entry">Built with <a href="https://hexo.io/" target="_blank">Hexo</a> and <a href="https://github.com/yelog/hexo-theme-3-hexo" target="_blank">3-hexo</a> theme</p>

    </div>
    <div class="full-toc">
        <button class="full" data-title="切换全屏 快捷键 s"><span class="min "></span></button>
<a class="" id="rocket" ></a>

    </div>
</div>

</body>
<script src="/blog/js/jquery.pjax.js?v=1.1.0" ></script>

<script src="/blog/js/script.js?v=1.1.0" ></script>
<script>
    var img_resize = 'default';
    function initArticle() {
        /*渲染对应的表格样式*/
        
            $("#post .pjax table").addClass("green_title");
        

        /*渲染打赏样式*/
        

        /*高亮代码块行号*/
        
        $('pre code').each(function(){
            var lines = $(this).text().trim().split('\n').length, widther='';
            if (lines>99) {
                widther = 'widther'
            }
            var $numbering = $('<ul/>').addClass('pre-numbering ' + widther).attr("unselectable","on");
            $(this).addClass('has-numbering ' + widther)
                    .parent()
                    .append($numbering);
            for(var i=1;i<=lines;i++){
                $numbering.append($('<li/>').text(i));
            }
        });
        

        /*访问数量*/
        
        $.getScript("//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js");
        

        /*代码高亮，行号对齐*/
        $('.pre-numbering').css('line-height',$('.has-numbering').css('line-height'));

        
        
    }

    /*打赏页面隐藏与展示*/
    

</script>

<!--加入行号的高亮代码块样式-->

<style>
    pre{
        position: relative;
        margin-bottom: 24px;
        border-radius: 10px;
        border: 1px solid #e2dede;
        background: #FFF;
        overflow: hidden;
    }
    code.has-numbering{
        margin-left: 30px;
    }
    code.has-numbering.widther{
        margin-left: 35px;
    }
    .pre-numbering{
        margin: 0;
        position: absolute;
        top: 0;
        left: 0;
        width: 20px;
        padding: 0.5em 3px 0.7em 5px;
        border-right: 1px solid #C3CCD0;
        text-align: right;
        color: #AAA;
        background-color: ;
    }
    .pre-numbering.widther {
        width: 35px;
    }
</style>

<!--自定义样式设置-->
<style>
    
    
    .nav {
        width: 542px;
    }
    .nav.fullscreen {
        margin-left: -542px;
    }
    .nav-left {
        width: 120px;
    }
    
    
    @media screen and (max-width: 1468px) {
        .nav {
            width: 492px;
        }
        .nav.fullscreen {
            margin-left: -492px;
        }
        .nav-left {
            width: 100px;
        }
    }
    
    
    @media screen and (max-width: 1024px) {
        .nav {
            width: 492px;
            margin-left: -492px
        }
        .nav.fullscreen {
            margin-left: 0;
        }
    }
    
    @media screen and (max-width: 426px) {
        .nav {
            width: 100%;
        }
        .nav-left {
            width: 100%;
        }
    }
    
    
    .nav-right .title-list nav a .post-title, .nav-right .title-list #local-search-result a .post-title {
        color: #383636;
    }
    
    
    .nav-right .title-list nav a .post-date, .nav-right .title-list #local-search-result a .post-date {
        color: #5e5e5f;
    }
    
    
    .nav-right nav a.hover, #local-search-result a.hover{
        background-color: #e2e0e0;
    }
    
    

    /*列表样式*/
    

    /* 背景图样式 */
    
    


    /*引用块样式*/
    

    /*文章列表背景图*/
    

    
</style>







</html>
